package com.panopset.sf.apps.blackjack;

import java.awt.FlowLayout;
import java.awt.Graphics;
import java.awt.Image;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.image.BufferedImage;
import java.util.ArrayList;
import java.util.List;

import javax.swing.ImageIcon;
import javax.swing.JLabel;
import javax.swing.JPanel;

import com.panopset.game.blackjack.BlackjackConfig;
import com.panopset.game.card.Card;
import com.panopset.game.card.CardDefinition;
import com.panopset.game.card.CardDefinition.Face;
import com.panopset.game.card.CardDefinition.Suit;
import com.panopset.sf.ComponentFactory;
import com.panopset.sf.apps.SwingCardPainter;

/**
 * Swing card selector class.
 * @author Karl Dinwiddie
 *
 */
public class CardSelector {
    public CardSelector(final BlackjackConfig config) {
        c = config;
    }
    private JPanel p;
    private final List<CardSelector.SelectionListener> ls
    = new ArrayList<CardSelector.SelectionListener>();

    private SwingCardPainter cardPainter;

    private SwingCardPainter getCardPainter() {
        if (cardPainter == null) {
            cardPainter = new SwingCardPainter(c);
        }
        return cardPainter;
    }

    private Integer fullHeight;

    private Integer fullWidth;

    private Integer getFullWidth() {
        if (fullWidth == null) {
            fullWidth = getCardPainter().getCardWidth() * 13;
        }
        return fullWidth;
    }

    private Integer getFullHeight() {
        if (fullHeight == null) {
            fullHeight = getCardPainter().getCardHeight() * 4;
        }
        return fullHeight;
    }
    private BufferedImage cardsImage;

    private Image getCardsImage() {
        if (cardsImage == null) {
            int w = getFullWidth();
            int h = getFullHeight();
            cardsImage = new BufferedImage(w, h, BufferedImage.TYPE_INT_RGB);
            Graphics g = cardsImage.getGraphics();
            int wd = 0;
            int hd = 0;
            for (CardDefinition.Suit s : getCardPainter().getOrder()) {
                for (CardDefinition.Face f : CardDefinition.Face.values()) {
                    Card c =  new Card(CardDefinition.find(f, s));
                    c.show();
                    getCardPainter().paintCard(g, c, wd, hd);
                    wd = wd + getCardPainter().getCardWidth();
                }
                wd = 0;
                hd = hd + getCardPainter().getCardHeight();
            }
        }
        return cardsImage;
    }

    public JPanel getPanel() {
        if (p == null) {
            p = new ComponentFactory().createPanel(new FlowLayout());
            final JLabel l = new JLabel(new ImageIcon(getCardsImage()));
            p.add(l);
            l.addMouseListener(new MouseAdapter() {
                public void mousePressed(MouseEvent e) {
                    int x = e.getX();
                    int y = e.getY();
                    int ch = 0;
                    int cw = 0;
                    Suit suit = getCardPainter().getOrder()[0];
                    for (Suit s : getCardPainter().getOrder()) {
                        if (y > ch) {
                            suit = s;
                        } else {
                            break;
                        }
                        ch += getCardPainter().getCardHeight();
                    }
                    Face face = Face.ACE;
                    for (Face f : Face.values()) {
                        if (x > cw) {
                            face = f;
                        } else {
                            break;
                        }
                        cw += getCardPainter().getCardWidth();
                    }
                    Card card = new Card(CardDefinition.find(face, suit));
                    for (SelectionListener sl : ls) {
                        sl.selected(card);
                    }
                }
            });
        }
        return p;
    }

    public void addSelectionListener(final CardSelector.SelectionListener sl) {
        ls.add(sl);
    }
    public interface SelectionListener {
        public void selected(final Card card);
    }
    private final BlackjackConfig c;
}
